package com.i360day.invoker.common;

import com.i360day.invoker.annotation.Argument;
import com.i360day.invoker.annotation.RemoteClient;
import com.i360day.invoker.annotation.RemoteModule;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.util.Assert;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 工具
 *
 * @author: liju.z
 * @Date: 2022-08-13 16:03
 **/
public class RemoteModuleUtils {

    /**
     * <p> @author liju.z <p>
     *
     * <p> @Description 获取remoteModule <p>
     *
     * <p> @Date  16:05 <p>
     *
     * <p> @Param interfaceClazz 接口类 <p>
     **/
    public static RemoteModule getRemoteModule(Class<?> interfaceClazz) {
        //获取父类配置
        Class<?>[] interfaceClazzSuper = interfaceClazz.getInterfaces();
        //获取到RemoteModule集合
        List<RemoteModule> remoteModuleList = Arrays.asList(interfaceClazzSuper)
                .stream()
                .map(clazz -> AnnotatedElementUtils.getMergedAnnotation(clazz, RemoteModule.class))
                .filter(remoteModule -> remoteModule != null)
                .collect(Collectors.toList());
        //判断service暴露类，如果有remoteModule，那么只能有一个remoteModule
        if (!remoteModuleList.isEmpty()) {
            Assert.isTrue(remoteModuleList.size() == 1, String.format("%s Can't inherit more than one module interface", interfaceClazz.getName()));
            return remoteModuleList.stream().findFirst().get();
        }
        //log提示，接口类中未出现RemoteModule标记
        return AnnotatedElementUtils.findMergedAnnotation(interfaceClazz, RemoteModule.class);
    }

    public static RemoteClient getRemoteClient(Class<?> interfaceClazz) {
        return AnnotatedElementUtils.getMergedAnnotation(interfaceClazz, RemoteClient.class);
    }

    public static Argument getRemoteClientArgument(Class<?> interfaceClazz, String name) {
        RemoteClient remoteClient = getRemoteClient(interfaceClazz);
        Argument[] arguments = remoteClient.argument();
        for (Argument argument : arguments) {
            if (argument.name().equals(name)) {
                return argument;
            }
        }
        return null;
    }

    public static boolean getRemoteClientArgumentEquals(Class<?> interfaceClazz, String name, Object value) {
        RemoteClient remoteClient = getRemoteClient(interfaceClazz);
        Argument[] arguments = remoteClient.argument();
        for (Argument argument : arguments) {
            return argument.name().equals(name) && value.equals(argument.value());
        }
        return false;
    }

//    public static Argument getRemoteClientArgumentValue(Class<?> interfaceClazz, String name){
//        RemoteClient remoteClient = getRemoteClient(interfaceClazz);
//        Argument[] arguments = remoteClient.argument();
//        for (Argument argument : arguments) {
//            if(argument.name().equals(name)){
//                Class<?> aClass = ClassUtils.getClass(argument.type());
//                Object o = aClass.getConstructor().newInstance(argument.value());
//                return aClass;
//            }
//        }
//        return null;
//    }
}
